package de.jmda.core.mproc.task;

import static de.jmda.core.mproc.ProcessingUtilities.getElementsAnnotatedWith;
import static de.jmda.core.util.StringUtil.sb;
import static java.lang.System.lineSeparator;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

import javax.lang.model.element.Element;

import org.apache.log4j.Logger;
import org.junit.Test;

import de.jmda.core.mproc.task.AbstractAnnotatedElementsTask;
import de.jmda.core.mproc.task.TaskException;
import de.jmda.core.mproc.task.TaskRunner;
import de.jmda.core.util.FileUtil;
import de.jmda.core.util.fileset.FileSet;
import de.jmda.core.util.fileset.FileSet.RuleSetUpdateMode;

public class JUTAnnotationsTask
{
	private static class AnnotationsTaskTest extends AbstractAnnotatedElementsTask
	{
		private final static Logger LOGGER =
	      Logger.getLogger(AnnotationsTaskTest.class);

		public AnnotationsTaskTest(
				Set<Class<? extends Annotation>> annotationTypes, FileSet fileset)
	  {
		  super(annotationTypes, fileset);
	  }

		@Override
	  public boolean execute() throws TaskException
	  {
			for (Class<? extends Annotation> annotationType : getAnnotationTypes())
			{
				StringBuffer b = sb("elements annotated with " + annotationType.getName());

				for (Element element : getElementsAnnotatedWith(annotationType))
				{
					b.append(lineSeparator() + element.getKind() + ": " + element.getSimpleName());
				}

				LOGGER.info(b.toString());
			}

			return false;
	  }
	}

	@Test
	public void testAnnotationsTask() throws IOException
	{
		Set<Class<? extends Annotation>> annotationTypes = new HashSet<>();

		annotationTypes.add(Test.class);
		annotationTypes.add(Deprecated.class);

		FileSet fileSet = new FileSet();
		fileSet.includeFile(
				new File(
						"src/test/java",
						FileUtil.toSourceFilePath(getClass())), RuleSetUpdateMode.ADD_RULE);

		assertTrue(fileSet.calculateFileSet().iterator().next().exists());

		AbstractAnnotatedElementsTask task = new AnnotationsTaskTest(annotationTypes, fileSet);

		TaskRunner.run(task);
	}
}